package com.clippick.clipboard;

import java.io.ByteArrayOutputStream;
import java.io.File;

import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.text.ClipboardManager;
//import android.util.Log;
import co.kr.clippick.R;

import com.clippick.MainActivity;
import com.clippick.api.GetApi;
import com.clippick.common.GlobalValue;
import com.clippick.common.Toasts;
import com.clippick.common.Utils;
//import com.clippick.database.FeedOrderDBAdapter;
//import com.clippick.database.HistoryDBAdapter;

@SuppressWarnings("deprecation")
public class PollingService extends Service {
	// common
	private Context mContext;
	public Context getServiceContext(){
		return mContext;
	}
	
	ConnectivityManager cntManager;
	
	// Polling thread
	private PollingThread pollingThread;

	// ClipBoard thread
	/**
	private GetClipBoardThread startClipBoard;
	*/
	
	// system clipboard
	private ClipboardManager systemClipboard;

	/** local database manager */
	/**
	private HistoryDBAdapter dbManager;
	private FeedOrderDBAdapter feedOrderDbManager;
	*/
	
	public void onDestroy() {
		super.onDestroy();
		this.unregisterReceiver(this.screenOnOffReceiver);
		this.unregisterReceiver(this.imageTansferReceiver);
		this.unregisterReceiver(this.mNetworkStateReceiver);
		this.unregisterReceiver(this.doConnectLongPollingReceiver);
		//startClipBoard.cancel();
		pollingThread.cancel();

		// if (dbManager.isOpenDBfile())
		// dbManager.close();

		// if (feedOrderDbManager.isOpenDBfile())
		// feedOrderDbManager.close();

		mContext = null;
		pollingThread = null;
		//startClipBoard = null;
		systemClipboard = null;
	}

	/**
	 * Task Order : <br>
	 * 1. SQLite3 Open <br>
	 * 2. Start polling System Clipboard </br> 3. Register Screen on/off
	 * Receiver
	 * */
	public void onCreate() {
		super.onCreate();
		mContext = this;
		cntManager = (ConnectivityManager) mContext
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		
		// Log.d("service", "onCreate");

		GlobalValue.IS_UPDATING = false;

		// system clipboard
		if (systemClipboard == null)
			systemClipboard = (ClipboardManager) mContext
					.getSystemService(Context.CLIPBOARD_SERVICE);

		// open local database
		/**
		String dbID = GlobalValue.USER_ID.replaceAll("@", "_")
				.replaceAll(".", "_").replaceAll("-", "_");

		if (dbManager == null) {
			dbManager = new HistoryDBAdapter(this, dbID);
		}

		// open order database manager
		if (feedOrderDbManager == null) {
			feedOrderDbManager = new FeedOrderDBAdapter(this, dbID);
		}
		*/

		// polling with system clipboard
//		if (startClipBoard == null) {
//			startClipBoard = new GetClipBoardThread(this, mUiHandler);
//		}
		final android.content.ClipboardManager clipMngr=
				(android.content.ClipboardManager)getSystemService(
									Context.CLIPBOARD_SERVICE);
		clipMngr.addPrimaryClipChangedListener(new android.content.
				ClipboardManager.OnPrimaryClipChangedListener() {
			
			@Override
			public void onPrimaryClipChanged() {
				if (!GlobalValue.USER_ID.equals("") && 
						!GlobalValue.IS_UPDATING) {
					ClipData clip=clipMngr.getPrimaryClip();
					ClipData.Item newItem = clip.getItemAt(0);
					String newItemText=(String)newItem.getText();
					
					/**
					 *  accept all changes don't check if data is duplicated
					 *  in database
					 */
					if (newItemText==null||
							newItemText.equals("")||
							GlobalValue.PrevClip.equals(newItemText))
						return;
					
					try {
						if (Utils.checkNetwokState(cntManager)) {
							GlobalValue.PrevClip = newItemText;
							GetApi api = new GetApi(PollingService.this);
							api.insertNewClip(newItemText);
							mUiHandler.sendEmptyMessage(0);
						}
					} catch (NullPointerException e) {
						e.printStackTrace();
					}
				}
			}
		});

		// polling with server-side
		if (pollingThread == null) {
			pollingThread = new PollingThread(this, mUiHandler);
		}

		/**
		dbManager.open();
		feedOrderDbManager.open();
		*/
		
		/**
		if (!startClipBoard.isAlive()) {
			startClipBoard.start();
		}
		*/

		// if (!pollingThread.isAlive()) {
		// pollingThread.start();
		// }

		try {
			// check screen is on/off
			IntentFilter screenOnFilter = new IntentFilter(
					Intent.ACTION_SCREEN_ON);
			registerReceiver(screenOnOffReceiver, screenOnFilter);
			IntentFilter screenOffFilter = new IntentFilter(
					Intent.ACTION_SCREEN_OFF);
			registerReceiver(screenOnOffReceiver, screenOffFilter);

			// register receiver image file to server AsyncTask
			IntentFilter transferImageFilter = new IntentFilter();
			transferImageFilter.addAction("com.clippick.TransferImage");
			mContext.registerReceiver(imageTansferReceiver, transferImageFilter);

			// register receiver in actibity or in service
			IntentFilter networkStateFilter = new IntentFilter(
					ConnectivityManager.CONNECTIVITY_ACTION);
			registerReceiver(mNetworkStateReceiver, networkStateFilter);

			// register receiver to doConnectLongPolling
			IntentFilter longpollFilter = new IntentFilter();
			longpollFilter.addAction("com.clippick.LongPoll");
			registerReceiver(doConnectLongPollingReceiver, longpollFilter);
		} catch (IllegalArgumentException e) {

		}
	}

	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		// Log.i("polling service", "onStartCommand()");
		// if (!dbManager.isOpenDBfile()) {
		// dbManager.open();
		// }
		//
		// if (!feedOrderDbManager.isOpenDBfile()) {
		// feedOrderDbManager.open();
		// }

		return START_STICKY;
	}

	// will be called when data modified
	Handler mUiHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.what == 0) {
				try {
					Toasts.showToast(mContext, "Clipped");
				} catch (NullPointerException e) {

				}

			} else if (msg.what == 1) {
				Toasts.showToast(mContext, "Sync Fail");

			} else if (msg.what == 2) {
				// ClipPick Copy

			} else if (msg.what == 3) {
				Toasts.showToast(mContext, "Clip Fail");

			} else if (msg.what == 4) {
				Toasts.showToast(mContext, "Check your network status");

			} else if (msg.what == 5) {
				// weak network service

			}
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	/**
	// access from GetPolling.class
	public HistoryDBAdapter getLocalDb() {
		return dbManager;
	}

	// access from GetPolling.class
	public FeedOrderDBAdapter getLocalOrderDb() {
		return feedOrderDbManager;
	}
	*/

	// access from GetPolling.class and GetClipBoard.class
//	@SuppressLint("NewApi")
//	public ClipboardManager getSystemClipboard() {
//		return systemClipboard;
//	}

	/** 새 클립을 시스템 클립보드에 밀어넣고 ClipPick UI를 업데이트한다. */
	@SuppressLint("NewApi")
	public void setNewClip(String content) {
		GlobalValue.isOnInsertSync = true;
		GlobalValue.AppClip = content;
		GlobalValue.PrevClip = content;
		GlobalValue.setAppClip(mContext, content);
		systemClipboard.setText(content);
	}

	/** transfer image file */

	private static int notiId = 0;

	class FileTask extends AsyncTask<Intent, String, String> {
		private NotificationManager notificationManager;
		private NotificationCompat.Builder mBuilder;

		protected void onPreExecute() {
			notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
			mBuilder = new NotificationCompat.Builder(mContext);

			mBuilder.setTicker("Image syncing...");
			mBuilder.setContentTitle("Image syncing...");
			mBuilder.setSmallIcon(R.drawable.icon_sub);
			// Sets the progress indicator to a max value, the current
			// completion percentage, and "determinate" state
			mBuilder.setProgress(0, 0, true);

			Intent intent = new Intent(mContext, MainActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
					| Intent.FLAG_ACTIVITY_CLEAR_TOP
					| Intent.FLAG_ACTIVITY_SINGLE_TOP);
			intent.putExtra("notificaion", true);
			PendingIntent contentIntent = PendingIntent.getActivity(mContext,
					0, intent, 0);
			mBuilder.setContentIntent(contentIntent);

			// Issues the notification
			if (notificationManager.hashCode() == notiId) {
				notiId++;
			}
			notificationManager.notify(notiId, mBuilder.build());
		}

		@Override
		protected String doInBackground(Intent... params) {
			GetApi api = new GetApi(mContext);

			Uri uri = (Uri) params[0].getExtras().getParcelable(
					Intent.EXTRA_STREAM);

			try {
				Bitmap bm = Utils.readBitmap(mContext, uri);
				String filePath = Environment.getExternalStorageDirectory()
						.toString() + "/.ClipPick/";
				File dir = new File(filePath);
				if (!dir.exists())
					dir.mkdirs();
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				bm.compress(CompressFormat.JPEG, 100, bos);

				// image file binary
				byte[] fileByte = bos.toByteArray();

				api.insertImageClip(fileByte);
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		protected void onPostExecute(String unused) {
			notificationManager.cancel(notiId);

			mBuilder.setProgress(0, 0, false);
			// Issues the notification
			mBuilder.setContentTitle("Image synced");
			mBuilder.setContentText("successfully synced");
			mBuilder.setTicker("Successfully synced");
			mBuilder.setContentText("completed syncing image");
			notificationManager.notify(notiId, mBuilder.build());
			notiId++;
		}
	}

	BroadcastReceiver imageTansferReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			new FileTask().execute(intent);
		}
	};

	/* check screen on off */
	BroadcastReceiver screenOnOffReceiver = new BroadcastReceiver() {

		public final String ScreenOff = "android.intent.action.SCREEN_OFF";
		public final String ScreenOn = "android.intent.action.SCREEN_ON";

		@Override
		public void onReceive(Context context, Intent intent) {

			if (intent.getAction().equals(ScreenOff)) {

			} else if (intent.getAction().equals(ScreenOn)) {

			}
		}
	};

	BroadcastReceiver doConnectLongPollingReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			doConnectLongPolling();
		}
	};

	/* network status broadcast receiver */
	public static int CONNECTED_COUNT = 0;

	private final BroadcastReceiver mNetworkStateReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			// do specific task(s) based on the current network state, such
			// as enabling queuing of HTTP requests when currentNetworkInfo
			// is
			// connected etc.
			if (CONNECTED_COUNT == 0) {
				doConnectLongPolling();
			}
		}
	};

	private void doConnectLongPolling() {
		if (Utils.checkNetwokState(cntManager)) {
			try {
				if (pollingThread.isAlive()) {
					pollingThread.cancel();
				}

				CONNECTED_COUNT = 1;
				pollingThread = new PollingThread((PollingService) mContext,
						mUiHandler);
				pollingThread.start();
			} catch (Exception e) {

			}
		} else {
			CONNECTED_COUNT = 0;
		}
	}
}
